package com.alibaba.chaosblade.box.toolsmgr.ansible.command;

import com.alibaba.chaosblade.box.toolsmgr.ansible.AnsibleCommand;
import com.alibaba.chaosblade.box.toolsmgr.ansible.AnsibleConstants;
import com.alibaba.chaosblade.box.toolsmgr.model.MgrRequest;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;

/**
 * hosts文件存储只存储固定变量，不存储可变参数
 *
 * @author: xinyuan.ymm
 * @create: 2022-01-07 9:41 PM
 */
@Slf4j
public class AnsibleAppendHostCommand implements AnsibleCommand, AnsibleConstants {

    /**
     * 根据管理请求生成Ansible追加主机命令
     *
     * @param mgrRequest 管理请求对象，包含目标主机IP、用户名等信息
     * @return 生成的Ansible追加主机命令字符串
     */
    @Override
    public String getCommand(MgrRequest mgrRequest) {
        log.info("[AnsibleAppendHostCommand] Generating command for host: {}", mgrRequest.getInstanceIp());
        // 检查是否有权限写入/etc/ansible/hosts文件
        File hostsFile = new File("/etc/ansible/hosts");
        if (hostsFile.canWrite()) {
            // 如果有权限，直接使用echo命令追加
            String command = String.format("echo '%s' >> /etc/ansible/hosts", mgrRequest.getInstanceIp());
            log.info("[AnsibleAppendHostCommand] Using direct write command: {}", command);
            return command;
        } else {
            log.warn("[AnsibleAppendHostCommand] No permission to write to /etc/ansible/hosts");
            // 如果没有权限，检查是否提供了密码
            if (mgrRequest.getInstancePassword() != null && !mgrRequest.getInstancePassword().isEmpty()) {
                // 如果提供了密码，使用sudo和密码执行命令
                String command = String.format("echo '%s' | sudo -S bash -c \"echo '%s' >> /etc/ansible/hosts\"", 
                                   mgrRequest.getInstancePassword(), mgrRequest.getInstanceIp());
                log.info("[AnsibleAppendHostCommand] Using sudo command with provided password");
                return command;
            } else {
                // 如果没有提供密码，使用用户目录下的hosts文件
                String userHostsPath = System.getProperty("user.home") + "/.ansible/hosts";
                File userHostsFile = new File(userHostsPath);
                
                // 确保用户目录下的ansible目录存在
                userHostsFile.getParentFile().mkdirs();
                
                try {
                    // 尝试写入用户目录下的hosts文件
                    Files.write(Paths.get(userHostsPath), 
                               (mgrRequest.getInstanceIp() + "\n").getBytes(), 
                               StandardOpenOption.CREATE, 
                               StandardOpenOption.APPEND);
                    // 使用指定的hosts文件运行ansible
                    String command = String.format("ansible -i %s %s", userHostsPath, mgrRequest.getInstanceIp());
                    log.info("[AnsibleAppendHostCommand] Using user-level hosts file: {}", userHostsPath);
                    return command;
                } catch (IOException e) {
                    log.error("[AnsibleAppendHostCommand] Failed to write to user hosts file: {}", e.getMessage());
                    // 如果仍然无法写入，返回一个带sudo的命令（需要手动输入密码）
                    String command = String.format("sudo bash -c \"echo '%s' >> /etc/ansible/hosts\"", mgrRequest.getInstanceIp());
                    log.info("[AnsibleAppendHostCommand] Falling back to sudo command");
                    return command;
                }
            }
        }
    }

    /**
     * 判断Ansible追加主机命令执行结果是否成功
     *
     * @param result                  命令执行结果列表
     * @param ignoreBackgroundTimeout 是否忽略后台超时（此参数在当前实现中未使用）
     * @return 如果执行结果表示成功则返回true，否则返回false
     */
    @Override
    public boolean resultPredicate(List<String> result, boolean ignoreBackgroundTimeout) {
        // 检查结果中是否包含错误信息
        for (String line : result) {
            if (line.contains("Permission denied") || line.contains("PermissionDenied")) {
                return false;
            }
            if (line.contains("command not found") || line.contains("sudo:")) {
                return false;
            }
            // 检查sudo密码是否错误
            if (line.contains("Sorry, try again") || line.contains("incorrect password")) {
                return false;
            }
            // 检查是否是ansible未安装的错误
            if (line.contains("ansible: not found") || line.contains("ansible: command not found")) {
                return false;
            }
        }
        // 如果没有明显的错误，则认为成功
        return true;
    }
}